var tileContainer;

/* =============== Common functions ============== */
function getIndex(ele) {
	var parent = ele.parentNode;
	var len = parent.children.length;
	for (var y = 0; y < len; y++) {
		if (parent.children[y] == ele) {
			return y;
		}
	}
	return -1;
}

function getPageScrollTop() {
    var yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {
      yScroll = document.documentElement.scrollTop;
    } else if (document.body) {
      yScroll = document.body.scrollTop;
    }
    return yScroll;
}

function getCSSProperty(element, property) {
	if(window.getComputedStyle) {
		var compStyle = window.getComputedStyle(element, null);
		var value = compStyle.getPropertyCSSValue(property);
		return parseInt(value.cssText);
	}
}

function removeStyle(ele) {
	ele.removeAttribute("style");
	for(var j=0; j < ele.children.length; j++) {
		removeStyle(ele.children[j]);
	}
}

function adjustDimensions() {
	var topCnt = document.getElementById("top-container");
	//reset styles
	removeStyle(topCnt);
	//adjust width and height
	for(i=0; i<topCnt.children.length; i++) {
		adjustDims(topCnt.children[i]);
	}
}

function adjustDims(ele) {
	if(ele.className == 'row' || ele.className == 'row multi') {
		
		var middleContainers = new Array();
		
		//adjust children width and height
		if(ele.children.length > 1) {
			var childMarginLeft = getCSSProperty(ele.children[1], "margin-left");
			var childWidthAvailable = ele.clientWidth - (ele.children.length-1) * childMarginLeft; 
			var expectedChildWidth = childWidthAvailable/ele.children.length;
			
			for(var cntCounter=0; cntCounter < ele.children.length; cntCounter++) {
				if(ele.children[cntCounter].className == 'middleContainer') {
					middleContainers.push(ele.children[cntCounter]);
				}
				
				//width 
				if(ele.children[cntCounter].clientWidth != expectedChildWidth) {
					if(ele.children[cntCounter].className == 'tileContainer') {
						ele.children[cntCounter].style.minWidth = (expectedChildWidth - getCSSProperty(ele.children[cntCounter], "padding-left") - getCSSProperty(ele.children[cntCounter], "padding-right")) + 'px';
					} else if(ele.children[cntCounter].className == 'middleContainer') {
						ele.children[cntCounter].style.minWidth = expectedChildWidth + 'px';
					}
				}
			}
			//setting height after setting width of all the child elements is necessary because manipulating both at
			//the same time leads to wrong height calculations
			for(var cntCounter=0; cntCounter < ele.children.length; cntCounter++) {
				//height
				if(ele.children[cntCounter].clientHeight != ele.clientHeight) {
					if(ele.children[cntCounter].className == 'tileContainer') {
						ele.children[cntCounter].style.minHeight = (ele.clientHeight - getCSSProperty(ele.children[cntCounter], "padding-top") - getCSSProperty(ele.children[cntCounter], "padding-bottom")) + 'px';
					} else if(ele.children[cntCounter].className == 'middleContainer') {
						ele.children[cntCounter].style.minHeight = ele.clientHeight + 'px';
					}
				}
			}
		} else {
			//width
			if(ele.children[0].clientWidth != ele.clientWidth) {
				ele.children[0].style.minWidth = (ele.clientWidth - getCSSProperty(ele.children[0], "padding-left") - getCSSProperty(ele.children[0], "padding-right")) + 'px';
			}
			//height
			if(ele.children[0].clientHeight != ele.clientHeight) {
				ele.children[0].style.minHeight = (ele.clientHeight - getCSSProperty(ele.children[0], "padding-top") - getCSSProperty(ele.children[0], "padding-bottom")) + 'px';
			}
		}
		
		for(var middleCntCounter=0; middleCntCounter < middleContainers.length; middleCntCounter++) {
			adjustDims(middleContainers[middleCntCounter]);
		}
		
	} else if (ele.className == 'middleContainer') {
		//width
		if(ele.children[0].clientWidth != ele.clientWidth) {
			ele.children[0].style.minWidth = ele.clientWidth + 'px';
		}
		//height
		if(ele.children[0].clientHeight != ele.clientHeight) {
			ele.children[0].style.minHeight = ele.clientHeight + 'px';
		}
		
		adjustDims(ele.children[0]);
	} else if (ele.className == 'row-container') {
		//width
		var totalRowHeight = 0;
		for(var rowCounter=0; rowCounter < ele.children.length; rowCounter++) {
			//adjust row width
			if(ele.children[rowCounter].clientWidth != ele.clientWidth) {
				ele.children[rowCounter].style.minWidth = ele.clientWidth + 'px';
			}
			totalRowHeight += ele.children[rowCounter].clientHeight;
		}
		//height
		if(ele.children.length == 1) {
			if(ele.children[0].clientHeight != ele.clientHeight) {
				ele.children[0].style.minHeight = ele.clientHeight;
			}
		} else {
			var marginTop = getCSSProperty(ele.children[1], "margin-top");
			var totalHeight = totalRowHeight +  (ele.children.length - 1) * marginTop;
			if(ele.clientHeight != totalHeight) {
				var extraHeight = ele.clientHeight - totalHeight;
				for( var rowCounter=0; rowCounter < ele.children.length; rowCounter++) {
					var rowClntHgt = ele.children[rowCounter].clientHeight;
					ele.children[rowCounter].style.minHeight = rowClntHgt + (extraHeight * rowClntHgt)/totalRowHeight + 'px';
				}
			}
		}
		
		for(var rowCounter=0; rowCounter < ele.children.length; rowCounter++) {
			adjustDims(ele.children[rowCounter]);
		}
	}
	
}

function createTileContainer() {
	var cntDiv = document.createElement("div");
	cntDiv.setAttribute("class", "tileContainer");
	cntDiv.setAttribute("oncontextmenu", "return showContextMenu(event);");
	cntDiv.setAttribute("ondragover", "dragOver(event)"); 
	cntDiv.setAttribute("ondrop", "drop(event)");
	return cntDiv;
}

/* ==================== Context menu item functions ================= */
function addColBefore() {
	var newCntDiv = createTileContainer();
	tileContainer.parentNode.insertBefore(newCntDiv, tileContainer);
	adjustDimensions();
}

function addColAfter() {
	var newCntDiv = createTileContainer();
	if(tileContainer.parentNode.lastElementChild == tileContainer) {
		tileContainer.parentNode.appendChild(newCntDiv);
	} else {
		tileContainer.parentNode.insertBefore(newCntDiv, tileContainer.nextElementSibling);
	}
	adjustDimensions();
}

function splitCol() {
	var newCntDiv = createTileContainer();
	tileContainer.parentNode.appendChild(newCntDiv);
	tileContainer.parentNode.className = 'row multi';
	adjustDimensions();
}

function splitRow() {
	if(tileContainer.parentNode.children.length == 1 && tileContainer.parentNode.parentNode.children.length == 1) {
		var row1 = document.createElement("div");
		row1.setAttribute("class", "row");
		row1.appendChild(createTileContainer());
		
		tileContainer.parentNode.parentNode.appendChild(row1);
	} else if(tileContainer.parentNode.children.length > 1) {
		var rowContainer = document.createElement("div");
		rowContainer.setAttribute("class", "row-container");
		//rows
		var row1 = document.createElement("div");
		row1.setAttribute("class", "row");
		var newTileCnt = tileContainer.cloneNode(true);
		newTileCnt.removeAttribute("style");
		row1.appendChild(newTileCnt);
		rowContainer.appendChild(row1);
		
		var row2 = document.createElement("div");
		row2.setAttribute("class", "row");
		row2.appendChild(createTileContainer());
		rowContainer.appendChild(row2);
		
		tileContainer.innerHTML = "";
		tileContainer.appendChild(rowContainer);
		tileContainer.setAttribute("class", "middleContainer");
		tileContainer.removeAttribute("oncontextmenu");
		tileContainer.removeAttribute("ondragover"); 
		tileContainer.removeAttribute("ondrop");
		tileContainer.removeAttribute("style");
	}
	
	adjustDimensions();
}

function addParentRowAbove() {
	var newCntDiv = createTileContainer();
	
	var newRowDiv = document.createElement("div");
	newRowDiv.setAttribute("class", "row");
	newRowDiv.appendChild(newCntDiv);
	
	if(tileContainer.parentNode.parentNode.parentNode.className == 'middleContainer') {
		tileContainer.parentNode.parentNode.parentNode.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode.parentNode.parentNode.parentNode);
	} else {
		tileContainer.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode);
	}
	adjustDimensions();
}

function addParentRowBelow() {
	var newCntDiv = createTileContainer();
	
	var newRowDiv = document.createElement("div");
	newRowDiv.setAttribute("class", "row");
	newRowDiv.appendChild(newCntDiv);
	
	if(tileContainer.parentNode.parentNode.parentNode.className == 'middleContainer') {
		tileContainer.parentNode.parentNode.parentNode.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode.parentNode.parentNode.parentNode.nextElementSibling);
	} else {
		tileContainer.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode.nextElementSibling);
	}
	adjustDimensions();
}

function addRowAbove() {
	var newCntDiv = createTileContainer();
	
	var newRowDiv = document.createElement("div");
	newRowDiv.setAttribute("class", "row");
	newRowDiv.appendChild(newCntDiv);
	
	tileContainer.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode);
	adjustDimensions();
}

function addRowBelow() {
	var newCntDiv = createTileContainer();
	
	var newRowDiv = document.createElement("div");
	newRowDiv.setAttribute("class", "row");
	newRowDiv.appendChild(newCntDiv);
	
	if(tileContainer.parentNode.parentNode.lastElementChild == tileContainer.parentNode) {
		tileContainer.parentNode.parentNode.appendChild(newRowDiv);
	} else {
		tileContainer.parentNode.parentNode.insertBefore(newRowDiv, tileContainer.parentNode.nextElementSibling);
	}
	adjustDimensions();
}

function deleteTileCnt() {
	var parentRow = tileContainer.parentNode;
	if(parentRow.children.length > 1) {
		parentRow.removeChild(tileContainer);
		if(parentRow.children.length == 1) {
			parentRow.className = 'row';
		}
	} else {
		
		var rowCnt = tileContainer.parentNode.parentNode;
		
		tileContainer.parentNode.parentNode.removeChild(tileContainer.parentNode);
		
		if(rowCnt.getAttribute('id') != 'top-container') {
			
			var middleCntParent = rowCnt.parentNode.parentNode;
			
			if(rowCnt.parentNode.className == 'middleContainer' && rowCnt.children.length == 1) {
				var tileCnt = rowCnt.children[0].children[0].cloneNode(true);
				rowCnt.parentNode.parentNode.replaceChild(tileCnt, rowCnt.parentNode);
			}
			
//			for(var i=0; i < middleCntParent.children.length; i++) {
//				removeStyle(middleCntParent.children[i]);
//			}
		}
	}
	
	adjustDimensions();
}

function deleteTile() {
	tileContainer.parentNode.removeChild(tileContainer);
	adjustDimensions();
}
	
/* =================== rendering context menu ================ */
function showContextMenu(ev){
	tileContainer = ev.currentTarget;
//	alert(containerTable.parentNode.nodeName);
	var menuList = document.createElement("ul");
	menuList.setAttribute("id", "contextMenu");
	menuList.setAttribute("class", "new-page-contextMenu");
	
	//for columns
	if(tileContainer.parentNode.children.length > 1) {
		if(tileContainer.parentNode.firstElementChild == tileContainer) {
			var item1 = document.createElement("li");
			item1.innerHTML = "Add Column (Before)";
			item1.setAttribute("onclick", "addColBefore()");
			menuList.appendChild(item1);
		}
		var item2 = document.createElement("li");
		item2.innerHTML = "Add Column (After)";
		item2.setAttribute("onclick", "addColAfter()");
		menuList.appendChild(item2);
	} 
	
	if(tileContainer.parentNode.children.length == 1) {
		var item1 = document.createElement("li");
		item1.innerHTML = "Split Cell(Column)";
		item1.setAttribute("onclick", "splitCol()");
		menuList.appendChild(item1);
	}

	//for rows
	if(tileContainer.parentNode.parentNode.children.length == 1 ||  tileContainer.parentNode.children.length > 1) {
		var item2 = document.createElement("li");
		item2.innerHTML = "Split Cell(Row)";
		item2.setAttribute("onclick", "splitRow()");
		menuList.appendChild(item2);
//		if(tileContainer.parentNode.parentNode.children.length > 1) {
			if(tileContainer.parentNode.parentNode.firstElementChild == tileContainer.parentNode) {
				var item3 = document.createElement("li");
				item3.innerHTML = "Add parent Row(Above)";
				item3.setAttribute("onclick", "addParentRowAbove()");
				menuList.appendChild(item3);
			}
//		}
		if(tileContainer.parentNode.children.length > 1) {
			var item4 = document.createElement("li");
			item4.innerHTML = "Add parent Row(Below)";
			item4.setAttribute("onclick", "addParentRowBelow()");
			menuList.appendChild(item4);
		}
	} else if(tileContainer.parentNode.parentNode.children.length > 1 ) {	
		if(tileContainer.parentNode.parentNode.firstElementChild == tileContainer.parentNode) {
			var item1 = document.createElement("li");
			item1.innerHTML = "Add Row (Above)";
			item1.setAttribute("onclick", "addRowAbove()");
			menuList.appendChild(item1);
		}
		var item2 = document.createElement("li");
		item2.innerHTML = "Add Row (Below)";
		item2.setAttribute("onclick", "addRowBelow()");
		menuList.appendChild(item2);
	}
	
	var del = true;
	if(document.getElementById("top-container").children.length == 1 && document.getElementById("top-container").children[0].children.length == 1) {
		del = false;
	}
	if(del) {
		var item3 = document.createElement("li");
		item3.innerHTML = "Delete";
		item3.setAttribute("onclick", "deleteTileCnt()");
		menuList.appendChild(item3);
		
		if(tileContainer.parentNode.className == 'row multi' && tileContainer.parentNode.children.length ==1) {
			tileContainer.parentNode.className = 'row';
		}
	}
	
	
	//position
	var scrollTop = getPageScrollTop();
	var Y = ev.clientY;
	menuList.style.top = (Y + scrollTop) + 'px';
	
	var X = ev.clientX;
	menuList.style.left = X + 'px';
	
	menuList.style.position = "absolute";
	menuList.style.zIndex = 10;

	document.body.appendChild(menuList);
	
	return false;
}

function showTileMenu(ev){
	tileContainer = ev.currentTarget;
//	alert(containerTable.parentNode.nodeName);
	var menuList = document.createElement("ul");
	menuList.setAttribute("id", "contextMenu");
	menuList.setAttribute("class", "new-page-contextMenu");
	
	var item = document.createElement("li");
	item.innerHTML = "Delete";
	item.setAttribute("onclick", "deleteTile(event)");
	menuList.appendChild(item);
	
	var item1 = document.createElement("li");
	item1.innerHTML = "Something1";
	menuList.appendChild(item1);
	
	var item2 = document.createElement("li");
	item2.innerHTML = "Something2";
	menuList.appendChild(item2);

	//position
	var scrollTop = getPageScrollTop();
	var Y = ev.clientY;
	menuList.style.top = (Y + scrollTop) + 'px';
	
	var X = ev.clientX;
	menuList.style.left = X + 'px';
	
	menuList.style.position = "absolute";
	menuList.style.zIndex = 10;

	document.body.appendChild(menuList);
	
	ev.stopPropagation();
	return false;
}

function hideContextMenu(){
	if(document.getElementById("contextMenu")) {
		document.body.removeChild(document.getElementById("contextMenu"));
	}
}


/* =============== drag and drop ================= */
function dragStart(ev) {
	ev.dataTransfer.effectAllowed = "move";
	
	var d = new Date();
	var currTime = d.getTime();
	ev.currentTarget.setAttribute("id", currTime);
	
	//This is important. Without this item can't be dragged
	ev.dataTransfer.setData("cmpntId", currTime);
}

function dragEnd(ele) {
	ele.removeAttribute("id");
}

function dragOver(ev) {
	if(ev.preventDefault) {
		ev.preventDefault();
	}
}

function changeBgColor(ev) {
	var dragElmntId = ev.dataTransfer.getData("cmpntId");
	var dragElmnt = document.getElementById(dragElmntId);
	if(dragElmnt != ev.currentTarget) {
		ev.currentTarget.style.backgroundColor = "grey";
	}
}

function removeTileStyle(ev) {
	var dragElmntId = ev.dataTransfer.getData("cmpntId");
	var dragElmnt = document.getElementById(dragElmntId);
	if(dragElmnt != ev.originalTarget) {
		ev.originalTarget.removeAttribute("style");
	}
}

function drop(ev) {
	var dragElmntId = ev.dataTransfer.getData("cmpntId");
	var dragElmnt = document.getElementById(dragElmntId);
	var newElmnt;
	var dropInSameCnt = false;
	var index = -1;
	if(dragElmnt.tagName == 'SPAN') {
		//dragging action
		newElmnt = document.createElement("div");
		newElmnt.setAttribute("class", "tile");
		newElmnt.setAttribute("draggable", "true");
		newElmnt.setAttribute("ondragstart", "dragStart(event);");
		newElmnt.setAttribute("ondragenter", "changeBgColor(event)");
		newElmnt.setAttribute("ondragleave", "removeTileStyle(event)");
		newElmnt.setAttribute("oncontextmenu", "return showTileMenu(event);");
		//get action
		newElmnt.innerHTML = dragElmnt.innerHTML.replace(/\t/gi, "").replace(/\n/gi, "");
		newElmnt.setAttribute("piston_start_action", newElmnt.innerHTML);
		
		var xmlhttp = new XMLHttpRequest();
		var func = 	function() {
				   		if (xmlhttp.readyState==4 && xmlhttp.status==200) {
				   			newElmnt.setAttribute("piston_tile_id", xmlhttp.responseText);
						}
					};
		sendAjaxRequest(xmlhttp, func, "GET", "/piston/ajax", null);
		
	} else {
		//dragging tile
		if(dragElmnt.parentNode == ev.currentTarget) {
			dropInSameCnt = true;
			index = getIndex(dragElmnt);
		}
		newElmnt = dragElmnt.parentNode.removeChild(dragElmnt);
	}
	
	if(ev.currentTarget == ev.originalTarget) {
		ev.currentTarget.appendChild(newElmnt);
	} else {
		if(dropInSameCnt && getIndex(ev.originalTarget) >= index) {
			if(getIndex(ev.originalTarget) != (ev.currentTarget.children.length -1)) {
				ev.currentTarget.insertBefore(newElmnt, ev.currentTarget.children[index].nextElementSibling);
			} else {
				ev.currentTarget.appendChild(newElmnt);
			}
		} else if(dropInSameCnt && getIndex(ev.originalTarget) < index) {
			ev.currentTarget.insertBefore(newElmnt, ev.currentTarget.children[getIndex(ev.originalTarget)]);
		} else {
			ev.currentTarget.insertBefore(newElmnt, ev.originalTarget);
		}
		//this is to change background color of tile when a tile is dropped on another tile
		ev.originalTarget.removeAttribute("style");
	}
	
	ev.stopPropagation();
	
	adjustDimensions();
}

function sendAjaxRequest(xmlhttp, func, type, url, params) {
	xmlhttp.onreadystatechange = func;
	xmlhttp.open(type, url);
	//this is very important otherwise firefox will not send post data
	if(type == 'POST') {
		xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
	}
	xmlhttp.send(params);
}

/* ============ button actions ============== */
function savePage() {
	var xmlhttp = new XMLHttpRequest();
	
	var func = 	function() {
			   		if (xmlhttp.readyState==4 && xmlhttp.status==200) {
			   			alert(xmlhttp.responseText);
					}
				};
	
	var ele = document.getElementById("top-container");
	var params = "pageXML=" + encodeURIComponent(ele.innerHTML);
	
	sendAjaxRequest(xmlhttp, func, "POST", "/piston/ajax", params);
}
